﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BotonJXC.Entity;
using BotonJXC.BLL;
using BotonJXC.Util;
using ComponentFactory.Krypton.Toolkit;
using NHibernate;
using BotonJXC.DAO;

namespace BotonJXC.Forms
{
    public partial class AllocationOrderForm : BaseMdiForm
    {
        #region member
        string[] _type;
        AllocatesBLL _allocateBll = new AllocatesBLL();
        StoreBLL _storeBLL = new StoreBLL();
        DepartmentBLL _departmentBLL = new DepartmentBLL();
        WarehouseBLL _warehouseBll = new WarehouseBLL();
        ProductBLL _productBll = new ProductBLL();
        IList<Store> _ourStores = null;
        IList<Store> _inStores = null;
        IDictionary<int, IList<Warehouse>> _depDict = new Dictionary<int, IList<Warehouse>>();
        int _pageStart = 0;
        int _totalCount;
        Allocates _queryAllocate = null;
        WarehouseProductBLL _wProductBll = new WarehouseProductBLL();
        /// <summary>
        /// 门店是否须相同
        /// </summary>
        bool _sameStore = true;
        #endregion

        #region form load
        public AllocationOrderForm()
        {
            InitializeComponent();
        }
        
        private void AllocationOrderForm_Load(object sender, EventArgs e)
        {
            if (!DesignMode)
            {
                InitForm();
            }
        }
        #endregion

        #region Property
        public Allocates CurAllocate { get; set; }
        #endregion

        #region method

        private void InitForm() {
            _type = this.Tag.ToString().Trim().Split(',');

            if ("1".Equals(_type[1])) {
                this.Text = "分店店内调拨";
                _ourStores = _inStores = _storeBLL.FindAll();
                kcbMStore.DataSource = kcbOutStore.DataSource = kcbInStore.DataSource = _ourStores;
                kcbOutStore.Enabled = false;
                kcbInStore.Enabled = false;
                _sameStore = true;
            }
            else if ("2".Equals(_type[1]))
            {
                this.Text = "分店同城调拨";

                _ourStores = _storeBLL.FindAll();

                _inStores = new List<Store>(_ourStores);

                kcbMStore.DataSource = kcbOutStore.DataSource = _ourStores;
                kcbInStore.DataSource = _inStores;
                kcbOutStore.Enabled = false;
                _sameStore = false;
            }
            else if ("3".Equals(_type[1]))
            {
                this.Text = "配送中心店内调拨单";
                _ourStores = _inStores = _storeBLL.FindAll();
                kcbMStore.DataSource = kcbOutStore.DataSource = kcbInStore.DataSource = _ourStores;
                kcbOutStore.Enabled = false;
                kcbInStore.Enabled = false;
                kcbGenPackingBill.Visible = true;
                _sameStore = true;
            }
            else if ("4".Equals(_type[1]))
            {
                this.Text = "加工间店内调拨";
                _ourStores = _inStores = _storeBLL.FindAll();
                kcbMStore.DataSource = kcbOutStore.DataSource = kcbInStore.DataSource = _ourStores;
                kcbOutStore.Enabled = false;
                kcbInStore.Enabled = false;
                _sameStore = true;
            }
            else if ("5".Equals(_type[1]))
            {
                this.Text = "配送中心行政领用";
                OutstoreLabel.Text = "存货地";
                InstoreLabel.Text = "行政部门";
                storeLabel.Text = "分店";
                klNumberLabel.Text = "数量合计";
                klInmoneyLabel.Text = "进价金额";
                klOutMoneyLabel.Text = "售价金额";

                DCDefPrice.HeaderText = "领用进价";
                DCProQuantity.HeaderText = "领用合计数";
                DCProAmount.HeaderText = "进价金额";
                DCUnit.HeaderText = "销售单位";

                klStatusLabel.Visible = true;
                klStatusLabelValue.Visible = true;
                klOutMoneyLabel.Visible = true;
                klOutMoneyLabelValue.Visible = true;

                batchColumn.Visible = true;
                colorCodeColumn.Visible = true;
                colorNameColumn.Visible = true;
                numberColumn.Visible = true;
                DCProSpec.Visible = true;
                typeSNColumn.Visible = true;
                typeNameColumn.Visible = true;

                DCTaxRate.Visible = true;

                _ourStores = _inStores = _storeBLL.FindAll();
                kcbMStore.DataSource = kcbOutStore.DataSource = kcbInStore.DataSource = _ourStores;

                kcbOutStore.Enabled = false;
                kcbInStore.Enabled = false;

                kcbOwnUse.Visible = true;

                _sameStore = true;
            }
            ClearForm();

            SetControlStatus();
        }

        /// <summary>
        /// 清空Form
        /// </summary>
        void ClearForm()
        {
            CurAllocate = null;
            udgvProductList.DataSource = null;
            kTbxSN.Text = "";
            ktbRemark.Text = "";
            ktbSalesman.Text = "";
            kcbOwnUse.Checked = false;
            kcbGenPackingBill.Checked = false;
            klCreater.Text = LoginForm.Account.Realname;
            klCreateTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            klAuditTime.Text = "";
            klAuditUser.Text = "";
            klPrintTime.Text = "";
            klStatusLabelValue.Text = "";
            klInmoneyLabelValue.Text = "";
            klNumberLabelValue.Text = "";
            klOutMoneyLabelValue.Text = "";            
        }

        void LoadStoreInfo()
        {
            
        }

        void CalcSumInfo(int rowIndex)
        {
            IList<AllocatesProducts> pros = udgvProductList.DataSource as IList<AllocatesProducts>;
            udgvProductList.Rows[rowIndex].Cells[DCProAmount.Name].Value = pros[rowIndex].Quantity * pros[rowIndex].Price;
            CalcSumInfo();
        }
        void CalcSumInfo()
        {
            double sumQuantity = 0;
            double sumMonery = 0;
            IList<AllocatesProducts> pros = udgvProductList.DataSource as IList<AllocatesProducts>;
            if (pros != null)
            {
                
                foreach (AllocatesProducts ap in pros)
                {
                    sumQuantity += ap.Quantity;
                    sumMonery += ap.Quantity * ap.Price;
                }
            }
            klInmoneyLabelValue.Text = sumMonery.ToString();
            klNumberLabelValue.Text = sumQuantity.ToString();
        }

        IList<Warehouse> LoadWarehouses(int storeId)
        {
            IList<Warehouse> deps = null;
            if (!_depDict.TryGetValue(storeId, out deps))
            {
                deps = _warehouseBll.FindWarehouseByStoreId(storeId, true);
                _depDict.Add(storeId, deps);
            }
            return deps;
        }

        string GetStatusName(short status)
        {
            if (status == (short)Status.None)
            {
                return "未审核";
            }
            else if (status == (short)Status.AuditPass)
            {
                return "已审核";
            }
            else if (status == (short)Status.AuditNoPass)
            {
                return "拒审";
            }
            else
            {
                return "未知";
             }
        }
        void FillForm()
        {
            if (CurAllocate != null)
            {
                udgvProductList.DataSource = new BindingList<AllocatesProducts>(CurAllocate.Products);
                CalcSumInfo();
                kTbxSN.Text = CurAllocate.AllocateSn;
                ktbRemark.Text = CurAllocate.Remark;
                ktbSalesman.Text = LoginForm.Account.Realname;
                klCreater.Text = CurAllocate.Account.Realname;
                if(CurAllocate.CreateTime.HasValue)
                    klCreateTime.Text = CurAllocate.CreateTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                klPrintTime.Text = CurAllocate.PrintTime.ToString();
                kcbGenPackingBill.Checked = "Y".Equals(CurAllocate.GenPicking);
                kcbOwnUse.Checked = "Y".Equals(CurAllocate.OwnUse);
                klStatusLabelValue.Text = GetStatusName(CurAllocate.AuditStatus);
                if (CurAllocate.AuditAccount != null)
                {
                    klAuditUser.Text = CurAllocate.AuditAccount.Realname;
                    klAuditTime.Text = CurAllocate.AuditTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                    ktbAuditRemark.Text = CurAllocate.AuditRemark;
                }
                SetStoreValue(kcbMStore, CurAllocate.OutStore.StoreId);
                SetStoreValue(kcbInStore, CurAllocate.InStore.StoreId);
                SetWarehouseValue(kcbOutStore, CurAllocate.OutWarehouse.WarehouseId);
                SetWarehouseValue(kcbInStore, CurAllocate.InWarehouse.WarehouseId);
            }
        }
        void FillAllocate()
        {
            if (CurAllocate == null)
                CurAllocate = new Allocates();
            CurAllocate.AllocateType = Utils.ToInt(_type[1], 0);
            CurAllocate.Remark = ktbRemark.Text;
            CurAllocate.OutWarehouse = kcbOutWarehouse.Tag as Warehouse;
            CurAllocate.InWarehouse = kcbInWarehouse.Tag as Warehouse;
            CurAllocate.OutStore = kcbOutStore.Tag as Store;
            CurAllocate.InStore = kcbInStore.Tag as Store;

            if (CurAllocate.AllocateId == 0)
            {
                CurAllocate.CreateTime = DateTime.Now;
                CurAllocate.Account = LoginForm.Account;
                CurAllocate.AuditStatus = (short)Status.None;
                CurAllocate.OwnUse = kcbOwnUse.Checked ? "Y" : "N";
                CurAllocate.GenPicking = kcbGenPackingBill.Checked ? "Y" : "N";
                CurAllocate.CreatePlace = GetCreatePlace();
                CurAllocate.AllocateSn = new BillSNGenerator().GeneratorBillSn(BillType.Allocate, BillSource.Store, CurAllocate.OutStore.StoreId);
                //设置归属门店
                CurAllocate.OrgId = LoginForm.StoreId;
                CurAllocate.OrgDepId = LoginForm.DepId;
            }

            foreach (AllocatesProducts ap in CurAllocate.Products)
                ap.Allocate = CurAllocate;
            
        }
        /// <summary>
        /// 获取当前单据产生地
        /// </summary>
        /// <returns></returns>
        short GetCreatePlace()
        {
            string type = _type[1];
            if (type == "1" || type == "2")
            {
                return (short)1;
            }
            else if (type == "4")
            {
                return 4;
            }
            else
            {
                return 2;
            }
        }
        void ValidInfo()
        {
            if (CurAllocate.Products.Count == 0)
            {
                
            }
        }
        void AuditInfo()
        {
            if (MessageBox.Show("审核确认", "确定要审核吗？", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
            {
                FillAllocate();
                CurAllocate.AuditAccount = LoginForm.Account;
                CurAllocate.AuditRemark = ktbAuditRemark.Text;
                CurAllocate.AuditStatus = (short)Status.AuditPass;
                CurAllocate.AuditTime = DateTime.Now;
                bool success = true;
                ITransaction trans = HBHelper.BeginTransaction();
                try
                {
                    _allocateBll.Save(CurAllocate);
                    //审核后直接增减库存
                    foreach (AllocatesProducts ap in CurAllocate.Products)
                    {
                        _wProductBll.OptQuantity(CurAllocate.OutWarehouse.WarehouseId, ap.Product.ProductId, -ap.Quantity);
                        _wProductBll.OptQuantity(CurAllocate.InWarehouse.WarehouseId, ap.Product.ProductId, ap.Quantity);
                    }
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    success = false;
                }
                finally
                {
                    HBHelper.Close();
                }
                if (success)
                {
                    MessageBox.Show("单据审核成功!");
                }
                else
                {
                    MessageBox.Show("单据审核失败!");
                }
            }
        }
        void SaveInfo()
        {
            FillAllocate();
            bool success = true;
            ITransaction trans = HBHelper.BeginTransaction();
            try
            {
                if (CurAllocate.AllocateId > 0)
                {
                    _allocateBll.Update(CurAllocate);
                }
                else
                {
                    _allocateBll.Save(CurAllocate);
                }
                trans.Commit();
            }
            catch (Exception ex)
            {
                trans.Rollback();
                success = false;
            }
            finally
            {
                HBHelper.Close();
            }
            if (success)
            {
                kTbxSN.Text = CurAllocate.AllocateSn;
                MessageBox.Show("单据保存成功!");
            }
            else
            {
                MessageBox.Show("单据保存失败!");
            }
        }

        void DeleteInfo()
        {
            if (CurAllocate != null)
            {
                ITransaction trans = HBHelper.BeginTransaction();
                try
                {
                    _allocateBll.Delete(CurAllocate);
                    trans.Commit();
                }
                catch (Exception)
                {
                    trans.Rollback();
                    throw;

                }
                finally
                {
                    HBHelper.Close();
                }
            }
        }

        void DeleteProInfo()
        {
            IList<AllocatesProducts> pros = (IList<AllocatesProducts>)udgvProductList.DataSource;
            ITransaction trans = HBHelper.BeginTransaction();
            try
            {
                foreach (DataGridViewRow r in udgvProductList.SelectedRows)
                {
                    AllocatesProducts item = r.DataBoundItem as AllocatesProducts;
                    if (item != null && item.AlloProId > 0)
                    {
                        _allocateBll.DeleteAllocateProduct(item);
                    }
                    pros.RemoveAt(r.Index);
                }
                trans.Commit();
            }
            catch (HibernateException ex)
            {
                trans.Rollback();
            }
            finally
            {
                HBHelper.Close();
            }
            udgvProductList.Refresh();
        }

        void SearchAllocates()
        {
            PageModel<Allocates> allocatePageModel = _allocateBll.findAllocatesByCondition(_queryAllocate, _pageStart, 1);
            _totalCount = allocatePageModel.TotalCount;
            if (allocatePageModel.Results.Count > 0)
            {
                if (allocatePageModel.Results[0].Products == null)
                {
                    allocatePageModel.Results[0].Products = new List<AllocatesProducts>();
                }

                CurAllocate = allocatePageModel.Results[0];
                FillForm();                
            }
            else
            {
                ClearForm();
            }
            SetControlStatus();
            tsbPrePage.Enabled = _pageStart > 0;
            tsbNextPage.Enabled = _pageStart < _totalCount - 1;
        }

        void SearchProducts()
        {
            ProductForm pf = new ProductForm();
            pf.DoubleListRowAction = ActionTypes.DoubleToReturn;
            pf.ProductSelected += new Forms.Events.ProductSelectedEventHandler(pf_ProductSelected);
            pf.ShowDialog();
        }

        void pf_ProductSelected(object sender, Events.ProductSelectedEventArgs e)
        {
            if (e.SelectedProduct != null)
            {
                IList<AllocatesProducts> products = udgvProductList.DataSource as IList<AllocatesProducts>;
                bool add = true;
                foreach (AllocatesProducts ap in products)
                {
                    if (ap.Product.ProductId == e.SelectedProduct.ProductId)
                    {
                        add = false;
                    }
                }
                if (add)
                {
                    AllocatesProducts nap = new AllocatesProducts();
                    nap.Product = e.SelectedProduct;
                    products.Add(nap);
                }
            }
            Form f = (Form)sender;
            f.Close();
        }
        void SetControlStatus()
        {
            if (CurAllocate == null)// 默认
            {
                SetToolStripItemEnabled(false, tsbReset, tsbDeletePro, tsbAuditBill, tsbDeleteBill, tsbLogsView, tsbQueryPro, tsbNextPage, tsbPrePage, tsbReport, tsbPrint, tsbSave);
                SetToolStripItemEnabled(true, tsbNewBill, tsbQueryBill, tsbQuit);
                udgvProductList.ReadOnly = true;
            }
            else if (CurAllocate.AllocateId == 0)
            {
                SetToolStripItemEnabled(false, tsbAuditBill, tsbDeleteBill, tsbLogsView, tsbNextPage, tsbPrePage, tsbPrint);
                SetToolStripItemEnabled(true, tsbReset, tsbDeletePro, tsbNewBill, tsbQueryBill, tsbQueryPro, tsbQuit, tsbReport, tsbSave);
                udgvProductList.AllowUserToAddRows = true;
                udgvProductList.ReadOnly = false;
            }
            else if (CurAllocate.AuditStatus != (short)Status.None)// 已审核
            {
                SetToolStripItemEnabled(false, tsbReset, tsbAuditBill, tsbDeleteBill, tsbSave, tsbDeletePro, tsbQueryPro);
                SetToolStripItemEnabled(true, tsbNewBill, tsbNextPage, tsbPrePage, tsbQueryBill, tsbQuit, tsbReport, tsbPrint, tsbLogsView);
                udgvProductList.ReadOnly = true;
            }
            else // 修改
            {
                SetToolStripItemEnabled(true, tsbReset, tsbAuditBill, tsbDeleteBill, tsbSave, tsbDeletePro, tsbQueryPro, tsbNewBill, tsbNextPage, tsbPrePage, tsbQueryBill, tsbQuit, tsbReport, tsbPrint, tsbLogsView);
                udgvProductList.AllowUserToAddRows = true;
                udgvProductList.ReadOnly = false;
            }
        }

        #endregion

        #region 控件事件

        private void tsbPrePage_Click(object sender, EventArgs e)
        {
            _pageStart--;
            SearchAllocates();
        }

        private void tsbNextPage_Click(object sender, EventArgs e)
        {
            _pageStart++;
            SearchAllocates();
        }

        private void tsbNewBill_Click(object sender, EventArgs e)
        {
            ClearForm();
            CurAllocate = new Allocates();
            CurAllocate.Products = new List<AllocatesProducts>();
            udgvProductList.DataSource = new BindingList<AllocatesProducts>(CurAllocate.Products);
            udgvProductList.Refresh();
            SetControlStatus();
        }

        private void tsbDeleteBill_Click(object sender, EventArgs e)
        {
            DeleteInfo();
            if (_pageStart == _totalCount - 1)
            {
                _pageStart--;
            }
            SearchAllocates();
        }

        private void tsbQueryBill_Click(object sender, EventArgs e)
        {
            AllocationOrderSearchForm aosf = new AllocationOrderSearchForm();
            aosf.AllocateType = Utils.ToInt(_type[1], 0);
            if (aosf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _queryAllocate = aosf.Allocate;
                SearchAllocates();
            }
        }

        private void tsbAuditBill_Click(object sender, EventArgs e)
        {
            AuditInfo();
            SetControlStatus();
        }

        private void tsbDeletePro_Click(object sender, EventArgs e)
        {
            DeleteProInfo();
        }

        private void tsbCancel_Click(object sender, EventArgs e)
        {

        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            SaveInfo();
            SetControlStatus();
        }

        private void tsbQueryPro_Click(object sender, EventArgs e)
        {
            SearchProducts();
        }

        private void tsbPrint_Click(object sender, EventArgs e)
        {

        }

        private void tsbQuit_Click(object sender, EventArgs e)
        {

        }

        private void kcbMStore_SelectedIndexChanged(object sender, EventArgs e)
        {
            IList<Store> stores = (IList<Store>)kcbMStore.DataSource;
            if (kcbMStore.SelectedIndex > -1)
            {
                ktbMStoreSn.Text = stores[kcbMStore.SelectedIndex].StoreSn;
                kcbMStore.Tag = stores[kcbMStore.SelectedIndex];
            }
            else
            {
                kcbMStore.Tag = null;
            }
        }

        private void kcbOutStore_SelectedIndexChanged(object sender, EventArgs e)
        {
            FillWarehouses(kcbOutStore, kcbOutWarehouse);
        }

        private void kcbInStore_SelectedIndexChanged(object sender, EventArgs e)
        {
            FillWarehouses(kcbInStore, kcbInWarehouse);
        }
        void FillWarehouses(KryptonComboBox storeComboBox, KryptonComboBox warehouseComboBox)
        {
            if (storeComboBox.SelectedIndex > -1)
            {
                IList<Store> stores = (IList<Store>)storeComboBox.DataSource;
                storeComboBox.Tag = stores[storeComboBox.SelectedIndex];
                warehouseComboBox.DataSource = new BindingList<Warehouse>(LoadWarehouses(stores[storeComboBox.SelectedIndex].StoreId));
            }
            else
            {
                warehouseComboBox.DataSource = null;
                storeComboBox.Tag = null;
            }
        }
        private void kcbOutWarehouse_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindWarehouse(kcbOutWarehouse);
        }

        private void BindWarehouse(KryptonComboBox kcbWarehoue)
        {
            if (kcbWarehoue.SelectedIndex > -1)
            {
                kcbWarehoue.Tag = (kcbWarehoue.DataSource as IList<Warehouse>)[kcbWarehoue.SelectedIndex];
            }
            else
            {
                kcbWarehoue.Tag = null;
            }
        }

        private void kcbInWarehouse_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindWarehouse(kcbInWarehouse);
        }
        private void udgvProductList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            string colName = udgvProductList.Columns[e.ColumnIndex].Name;
            IList<AllocatesProducts> pros = udgvProductList.DataSource as IList<AllocatesProducts>;
            if (colName == DCProCode.Name)
            {
                Product pro = _productBll.GetProductByCode(udgvProductList.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString());
                if (pro != null)
                {
                    pros[e.RowIndex].Product = pro;
                    pros[e.RowIndex].Price = pro.OutPrice;
                }
                else
                {
                    
                }
            }
            else if (colName == DCProQuantity.Name)
            {

                CalcSumInfo(e.RowIndex);
            }
            udgvProductList.Refresh();
        }

        private void udgvProductList_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            string colName = udgvProductList.Columns[e.ColumnIndex].Name;
            AllocatesProducts ars = udgvProductList.Rows[e.RowIndex].DataBoundItem as AllocatesProducts;
            if (ars != null)
            {
                if (colName == "DCProName" && ars.Product != null)
                {
                    e.Value = ars.Product.ProductName;
                }
                else if (colName == "DCPackSpec" && ars.Product != null)
                {
                    e.Value = ars.Product.PackSpec;
                }
                else if (colName == "DCBarcode" && ars.Product != null)
                {
                    e.Value = ars.Product.ProductName;
                }
                else if (colName == "DCUnit" && ars.Product != null && ars.Product.Unit != null)
                {
                    e.Value = ars.Product.Unit.UnitName;
                }
                else if (colName == "DCProAmount" && ars.Product != null)
                {
                    e.Value = ars.Product.OutPrice * ars.Quantity;
                }
                else if (colName == "DCDefPrice" && ars.Product != null)
                {
                    e.Value = ars.Product.OutPrice;
                }
                else if (colName == DCProCode.Name && ars.Product != null)
                {
                    e.Value = ars.Product.ProductCode;
                }
            }
        }

        private void udgvProductList_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            e.Cancel = false;
        }
        #endregion
    }
}
